import pyrtl
import or1200_definitions
from or1200_iwb_biu import Or1200IwbBiu
from or1200_wb_biu import Or1200wbbiu
from or1200_cpu import Or1200Cpu
from or1200_qmem_top import Or1200QmemTop
from or1200_sb import Or1200sb
from or1200_du import Or1200Du
from or1200_pic import Or1200Pic
from or1200_tt import Or1200tt
from or1200_pm import Or1200Pm

dw = or1200_definitions.OR1200_OPERAND_WIDTH
aw = or1200_definitions.OR1200_OPERAND_WIDTH
ppic_ints = or1200_definitions.OR1200_PIC_INTS

class Or1200_top(object):
    def __init__(self):
        # System
        self.clk_i = pyrtl.Input(bitwidth=1, name='Or1200_top_clk_i')
        self.rst_i = pyrtl.Input(bitwidth=1, name='Or1200_top_rst_i')
        self.clmode_i = pyrtl.Input(bitwidth=2, name='Or1200_top_clmode_i')    # 00 WB=RISC, 01 WB=RISC/2, 10 N/A, 11 WB=RISC/4
        self.pic_ints_i = pyrtl.Input(bitwidth=ppic_ints, name='Or1200_top_pic_ints_i')

        # Instruction WISHBONE interface
        self.iwb_clk_i = pyrtl.Input(bitwidth=1, name='Or1200_top_iwb_clk_i')  # clock input
        self.iwb_rst_i = pyrtl.Input(bitwidth=1, name='Or1200_top_iwb_rst_i')  # reset input
        self.iwb_ack_i = pyrtl.Input(bitwidth=1, name='Or1200_top_iwb_ack_i')  # normal termination
        self.iwb_err_i = pyrtl.Input(bitwidth=1, name='Or1200_top_iwb_err_i')  # termination w/ error
        self.iwb_rty_i = pyrtl.Input(bitwidth=1, name='Or1200_top_iwb_rty_i')  # termination w/ retry
        self.iwb_dat_i = pyrtl.Input(bitwidth=dw, name='Or1200_top_iwb_dat_i') # input data bus

        self.iwb_cyc_o = pyrtl.Output(bitwidth=1)#, name='iwb_cyc_o')     # cycle valid output
        self.iwb_adr_o = pyrtl.Output(bitwidth=dw)#, name='iwb_adr_o')    # address bus outputs
        self.iwb_stb_o = pyrtl.Output(bitwidth=1)#, name='iwb_stb_o')     # strobe output
        self.iwb_we_o = pyrtl.Output(bitwidth=1)#, name='iwb_we_o')       # indicates write transfer
        self.iwb_sel_o = pyrtl.Output(bitwidth=4)#, name='iwb_sel_o')     # byte select outputs
        self.iwb_dat_o = pyrtl.Output(bitwidth=dw)#, name='iwb_dat_o')    # output data bus
        self.iwb_cab_o = pyrtl.Output(bitwidth=1)#, name='iwb_cab_o')     # indicates consecutive address burst

        # Data WISHBONE interface
        self.dwb_clk_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dwb_clk_i')      # clock input
        self.dwb_rst_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dwb_rst_i')      # reset input
        self.dwb_ack_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dwb_ack_i')      # normal termination
        self.dwb_err_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dwb_err_i')      # termination w/ error
        self.dwb_rty_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dwb_rty_i')      # termination w/ retry
        self.dwb_dat_i = pyrtl.Input(bitwidth=dw, name='Or1200_top_dwb_dat_i')     # input data bus

        self.dwb_cyc_o = pyrtl.Output(bitwidth=1)#, name='dwb_cyc_o')     # cycle valid output
        self.dwb_adr_o = pyrtl.Output(bitwidth=dw)#, name='dwb_adr_o')    # address bus outputs
        self.dwb_stb_o = pyrtl.Output(bitwidth=1)#, name='dwb_stb_o')     # strobe output
        self.dwb_we_o = pyrtl.Output(bitwidth=1)#, name='dwb_we_o')       # indicates write transfer
        self.dwb_sel_o = pyrtl.Output(bitwidth=4)#, name='dwb_sel_o')     # byte select outputs
        self.dwb_dat_o = pyrtl.Output(bitwidth=dw)#, name='dwb_dat_o')    # output data bus

        self.dwb_cab_o = pyrtl.Output(bitwidth=dw)#, name='dwb_cab_o')    # indicates consecutive address burst

        # External Debug Interface
        self.dbg_stall_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dbg_stall_i')   # External Stall Input
        self.dbg_ewt_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dbg_ewt_i')       # External Watchpoint Trigger Input
        self.dbg_stb_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dbg_stb_i')       # External Address/Data Strobe
        self.dbg_we_i = pyrtl.Input(bitwidth=1, name='Or1200_top_dbg_we_i')         # External Write Enable
        self.dbg_adr_i = pyrtl.Input(bitwidth=aw, name='Or1200_top_dbg_adr_i')      # External Address Input
        self.dbg_dat_i = pyrtl.Input(bitwidth=dw, name='Or1200_top_dbg_dat_i')      # External Data Input

        self.dbg_lss_o = pyrtl.Output(bitwidth=4)#, name='dbg_lss_o')     # External Load/Store Unit Status
        self.dbg_is_o = pyrtl.Output(bitwidth=1)#, name='dbg_is_o')       # External Insn Fetch Status
        self.dbg_wp_o = pyrtl.Output(bitwidth=11)#, name='dbg_wp_o')       # Watchpoints Outputs
        self.dbg_bp_o = pyrtl.Output(bitwidth=1)#, name='dbg_bp_o')       # Breakpoint Output
        self.dbg_dat_o = pyrtl.Output(bitwidth=dw)#, name='dbg_dat_o')       # External Data Output
        self.dbg_ack_o = pyrtl.Output(bitwidth=1)#, name='dbg_ack_o')       # External Data Acknowledge (not WB compatible)

        # Power Management
        self.pm_cpustall_i = pyrtl.Input(bitwidth=1, name='Or1200_top_pm_cpustall_i')
        self.pm_clksd_o = pyrtl.Output(bitwidth=1)#, name='pm_clksd_o')
        self.pm_dc_gate_o = pyrtl.Output(bitwidth=1)#, name='pm_dc_gate_o')
        self.pm_ic_gate_o = pyrtl.Output(bitwidth=1)#, name='pm_ic_gate_o')
        self.pm_dmmu_gate_o = pyrtl.Output(bitwidth=1)#, name='pm_dmmu_gate_o')
        self.pm_immu_gate_o = pyrtl.Output(bitwidth=1)#, name='pm_immu_gate_o')
        self.pm_tt_gate_o = pyrtl.Output(bitwidth=1)#, name='pm_tt_gate_o')
        self.pm_cpu_gate_o = pyrtl.Output(bitwidth=1)#, name='pm_cpu_gate_o')
        self.pm_wakeup_o = pyrtl.Output(bitwidth=1)#, name='pm_wakeup_o')
        self.pm_lvolt_o = pyrtl.Output(bitwidth=1)#, name='pm_lvolt_o')

        # SB to BIU
        self.sbbiu_cyc_sb = pyrtl.WireVector(bitwidth=1, name='sbbiu_cyc_sb')
        self.sbbiu_dat_sb = pyrtl.WireVector(bitwidth=dw, name='sbbiu_dat_sb ')
        self.sbbiu_adr_sb = pyrtl.WireVector(bitwidth=aw, name='sbbiu_adr_sb ')
        self.sbbiu_stb_sb = pyrtl.WireVector(bitwidth=1, name='sbbiu_stb_sb ')
        self.sbbiu_we_sb = pyrtl.WireVector(bitwidth=1, name='sbbiu_we_sb  ')
        self.sbbiu_sel_sb = pyrtl.WireVector(bitwidth=4, name='sbbiu_sel_sb ')
        self.sbbiu_cab_sb = pyrtl.WireVector(bitwidth=1, name='sbbiu_cab_sb ')
        self.sbbiu_dat_biu = pyrtl.WireVector(bitwidth=dw, name='sbbiu_dat_biu')
        self.sbbiu_ack_biu = pyrtl.WireVector(bitwidth=1, name='sbbiu_ack_biu')
        self.sbbiu_err_biu = pyrtl.WireVector(bitwidth=1, name='sbbiu_err_biu')

        # CPU's SPR access to various RISC units (shared wires)
        self.supv = pyrtl.WireVector(bitwidth=1, name='supv')
        self.spr_addr = pyrtl.WireVector(bitwidth=aw, name='spr_addr')
        self.spr_dat_cpu = pyrtl.WireVector(bitwidth=dw, name='spr_dat_cpu')
        self.spr_cs = pyrtl.WireVector(bitwidth=32, name='spr_cs')
        self.spr_we = pyrtl.WireVector(bitwidth=1, name='spr_we')

        # CPU and data memory subsystem
        self.dc_en = pyrtl.WireVector(bitwidth=1, name='dc_en')
        self.dcpu_adr_cpu = pyrtl.WireVector(bitwidth=32, name='dcpu_adr_cpu')
        self.dcpu_cycstb_cpu = pyrtl.WireVector(bitwidth=1, name='dcpu_cycstb_cpu')
        self.dcpu_we_cpu = pyrtl.WireVector(bitwidth=1, name='dcpu_we_cpu')
        self.dcpu_sel_cpu = pyrtl.WireVector(bitwidth=4, name='dcpu_sel_cpu')
        self.dcpu_tag_cpu = pyrtl.WireVector(bitwidth=4, name='dcpu_tag_cpu')
        self.dcpu_dat_cpu = pyrtl.WireVector(bitwidth=32, name='dcpu_dat_cpu')
        self.dcpu_dat_qmem = pyrtl.WireVector(bitwidth=32, name='dcpu_dat_qmem')
        self.dcpu_ack_qmem = pyrtl.WireVector(bitwidth=1, name='dcpu_ack_qmem')
        self.dcpu_rty_qmem = pyrtl.WireVector(bitwidth=1, name='dcpu_rty_qmem')
        self.dcpu_err_dmmu = pyrtl.WireVector(bitwidth=1, name='dcpu_err_dmmu')
        self.dcpu_tag_dmmu = pyrtl.WireVector(bitwidth=4, name='dcpu_tag_dmmu')

        # CPU and insn memory subsystem
        self.ic_en = pyrtl.WireVector(bitwidth=1, name='ic_en')
        self.icpu_adr_cpu = pyrtl.WireVector(bitwidth=32, name='icpu_adr_cpu')
        self.icpu_cycstb_cpu = pyrtl.WireVector(bitwidth=1, name='icpu_cycstb_cpu')
        self.icpu_sel_cpu = pyrtl.WireVector(bitwidth=4, name='icpu_sel_cpu')
        self.icpu_tag_cpu = pyrtl.WireVector(bitwidth=4, name='icpu_tag_cpu')
        self.icpu_dat_qmem = pyrtl.WireVector(bitwidth=32, name='icpu_dat_qmem')
        self.icpu_ack_qmem = pyrtl.WireVector(bitwidth=1, name='icpu_ack_qmem')
        self.icpu_err_immu = pyrtl.WireVector(bitwidth=1, name='icpu_err_immu')
        self.icpu_tag_immu = pyrtl.WireVector(bitwidth=32, name='icpu_tag_immu')
        self.icpu_rty_immu = pyrtl.WireVector(bitwidth=1, name='icpu_rty_immu')

        # QMEM and BIU
        self.icqmem_adr_qmem = pyrtl.WireVector(bitwidth=aw, name='icqmem_adr_qmem')
        self.icqmem_err_ic = pyrtl.WireVector(bitwidth=1, name='icqmem_err_ic')
        self.icqmem_cycstb_qmem = pyrtl.WireVector(bitwidth=1, name='icqmem_cycstb_qmem')
        self.icqmem_ci_qmem = pyrtl.WireVector(bitwidth=1, name='icqmem_ci_qmem')
        self.icqmem_dat_ic = pyrtl.WireVector(bitwidth=32, name='icqmem_dat_ic')
        self.icqmem_ack_ic = pyrtl.WireVector(bitwidth=1, name='icqmem_ack_ic')
        self.icbiu_cab_ic = pyrtl.WireVector(bitwidth=1, name='icbiu_cab_ic')

        # QMEM and SB
        self.dcqmem_adr_qmem = pyrtl.WireVector(bitwidth=aw, name='dcqmem_adr_qmem')
        self.dcqmem_rty_dc = pyrtl.WireVector(bitwidth=1, name='dcqmem_rty_dc')
        self.dcqmem_err_dc = pyrtl.WireVector(bitwidth=1, name='dcqmem_err_dc')
        self.dcqmem_tag_dc = pyrtl.WireVector(bitwidth=4, name='dcqmem_tag_dc')
        self.dcqmem_cycstb_qmem = pyrtl.WireVector(bitwidth=1, name='dcqmem_cycstb_qmem')
        self.dcqmem_ci_qmem = pyrtl.WireVector(bitwidth=1, name='dcqmem_ci_qmem')
        self.dcqmem_dat_dc = pyrtl.WireVector(bitwidth=32, name='dcqmem_dat_dc')
        self.dcqmem_dat_qmem = pyrtl.WireVector(bitwidth=32, name='dcqmem_dat_qmem')
        self.dcqmem_we_qmem = pyrtl.WireVector(bitwidth=1, name='dcqmem_we_qmem')
        self.dcqmem_sel_qmem = pyrtl.WireVector(bitwidth=4, name='dcqmem_sel_qmem')
        self.dcqmem_ack_dc = pyrtl.WireVector(bitwidth=1, name='dcqmem_ack_dc')
        self.dcsb_cab_dc = pyrtl.WireVector(bitwidth=1, name='dcsb_cab_dc')

        # Connection between CPU and PIC
        self.spr_dat_pic = pyrtl.WireVector(bitwidth=dw, name='spr_dat_pic')
        self.pic_wakeup = pyrtl.WireVector(bitwidth=1, name='pic_wakeup')
        self.sig_int = pyrtl.WireVector(bitwidth=1, name='sig_int')

        # Connection between CPU and PM
        self.spr_dat_pm = pyrtl.WireVector(bitwidth=dw, name='spr_dat_pm')

        # CPU and TT
        self.spr_dat_tt = pyrtl.WireVector(bitwidth=dw, name='spr_dat_tt')
        self.sig_tick = pyrtl.WireVector(bitwidth=1, name='sig_tick')

        # Debug port and caches/MMUs
        self.spr_dat_du = pyrtl.WireVector(bitwidth=dw, name='spr_dat_du')
        self.du_stall = pyrtl.WireVector(bitwidth=1, name='du_stall')
        self.du_addr = pyrtl.WireVector(bitwidth=dw, name='du_addr')
        self.du_dat_du = pyrtl.WireVector(bitwidth=dw, name='du_dat_du')
        self.du_read = pyrtl.WireVector(bitwidth=1, name='du_read')
        self.du_write = pyrtl.WireVector(bitwidth=1, name='du_write')
        self.du_except = pyrtl.WireVector(bitwidth=13, name='du_except')
        self.du_dsr = pyrtl.WireVector(bitwidth=or1200_definitions.OR1200_DU_DSR_WIDTH, name='du_dsr')
        self.du_dat_cpu = pyrtl.WireVector(bitwidth=dw, name='du_dat_cpu')
        self.du_hwbkpt = pyrtl.WireVector(bitwidth=1, name='du_hwbkpt')
        self.ex_freeze = pyrtl.WireVector(bitwidth=1, name='ex_freeze')
        self.ex_insn = pyrtl.WireVector(bitwidth=32, name='ex_insn####################################    ')
        self.id_pc = pyrtl.WireVector(bitwidth=32, name='id_pc')
        self.branch_op = pyrtl.WireVector(bitwidth=or1200_definitions.OR1200_BRANCHOP_WIDTH, name='branch_op')
        self.spr_dat_npc = pyrtl.WireVector(bitwidth=32, name='spr_dat_npc')
        self.rf_dataw = pyrtl.WireVector(bitwidth=32, name='rf_dataw')
        self.icqmem_sel_qmem = pyrtl.WireVector(bitwidth=4, name='icqmem_sel_qmem')
        self.icqmem_tag_qmem = pyrtl.WireVector(bitwidth=4, name='icqmem_tag_qmem')
        self.dcqmem_tag_qmem = pyrtl.WireVector(bitwidth=4, name='dcqmem_tag_qmem')

        ####################################
        # module connection
        ####################################
        # Instantiation of Instruction WISHBONE BIU
        iwbbiu = Or1200IwbBiu()
        iwbbiu.rst = self.rst_i
        iwbbiu.clmode = self.clmode_i

        iwbbiu.wb_clk_i = self.iwb_clk_i
        iwbbiu.wb_rst_i = self.iwb_rst_i
        iwbbiu.wb_ack_i = self.iwb_ack_i
        iwbbiu.wb_err_i = self.iwb_err_i
        iwbbiu.wb_rty_i = self.iwb_rty_i
        iwbbiu.biu_dat_i = self.iwb_dat_i
        self.iwb_cyc_o = iwbbiu.wb_cyc_o
        self.iwb_adr_o = iwbbiu.wb_adr_o
        self.iwb_stb_o = iwbbiu.wb_stb_o
        self.iwb_we_o = iwbbiu.wb_we_o
        self.iwb_sel_o = iwbbiu.wb_sel_o
        self.iwb_dat_o = iwbbiu.wb_dat_o
        self.iwb_cab_o = iwbbiu.wb_cab_o

        iwbbiu.biu_adr_i = self.icqmem_adr_qmem
        iwbbiu.biu_cyc_i = self.icqmem_cycstb_qmem
        iwbbiu.biu_stb_i = self.icqmem_cycstb_qmem
        iwbbiu.biu_sel_i = self.icqmem_sel_qmem
        self.icqmem_dat_ic = iwbbiu.biu_dat_o
        self.icqmem_ack_ic = iwbbiu.biu_ack_o
        self.icqmem_err_ic = iwbbiu.biu_err_o
        iwbbiu.biu_we_i = pyrtl.Const(0b0, bitwidth=1)
        iwbbiu.biu_dat_i = pyrtl.Const(0b0, bitwidth=32)
        iwbbiu.biu_cab_i = self.icbiu_cab_ic

        # Instantiation of Data WISHBONE BIU
        wbbiu = Or1200wbbiu()
        wbbiu.rst = self.rst_i
        wbbiu.clmode = self.clmode_i

        wbbiu.wb_clk_i = self.dwb_clk_i
        wbbiu.wb_rst_i = self.dwb_rst_i
        wbbiu.wb_ack_i = self.dwb_ack_i
        wbbiu.wb_err_i = self.dwb_err_i
        wbbiu.wb_rty_i = self.dwb_rty_i
        wbbiu.wb_dat_i = self.dwb_dat_i
        self.dwb_cyc_o = wbbiu.wb_cyc_o
        self.dwb_adr_o = wbbiu.wb_adr_o
        self.dwb_stb_o = wbbiu.wb_stb_o
        self.dwb_we_o = wbbiu.wb_we_o
        self.dwb_sel_o <<= wbbiu.wb_sel_o
        self.dwb_dat_o <<= wbbiu.wb_dat_o
        self.dwb_cab_o <<= wbbiu.wb_cab_o

        wbbiu.biu_dat_i <<= self.sbbiu_dat_sb
        wbbiu.biu_adr_i <<= self.sbbiu_adr_sb
        wbbiu.biu_cyc_i <<= self.sbbiu_cyc_sb
        wbbiu.biu_stb_i <<= self.sbbiu_stb_sb
        wbbiu.biu_we_i <<= self.sbbiu_we_sb
        wbbiu.biu_sel_i <<= self.sbbiu_sel_sb
        wbbiu.biu_cab_i <<= self.sbbiu_cab_sb
        self.sbbiu_dat_biu <<= wbbiu.biu_dat_o
        self.sbbiu_ack_biu <<= wbbiu.biu_ack_o
        self.sbbiu_err_biu <<= wbbiu.biu_err_o

        # Instantiation of CPU
        #######################################

        #######################################

        self.icpu_pn_r = pyrtl.Register(bitwidth=32, name='icpu_pn_r')
        self.page_cross = pyrtl.WireVector(bitwidth=1, name='page_cross')

        # Instantiation of embedded memory - qmem
        #######################################

        #######################################

        # Instantiation of Store Buffer
        storebuffer = Or1200sb()
        storebuffer.rst <<= self.rst_i

        storebuffer.dcsb_adr_i <<= self.dcqmem_adr_qmem
        storebuffer.dcsb_cyc_i <<= self.dcqmem_cycstb_qmem
        storebuffer.dcsb_stb_i <<= self.dcqmem_cycstb_qmem
        storebuffer.dcsb_sel_i <<= self.dcqmem_sel_qmem
        self.dcqmem_dat_dc <<= storebuffer.dcsb_dat_o
        self.dcqmem_ack_dc <<= storebuffer.dcsb_ack_o
        self.dcqmem_err_dc <<= storebuffer.dcsb_err_o
        storebuffer.dcsb_we_i = self.dcqmem_we_qmem
        storebuffer.dcsb_dat_i = self.dcqmem_dat_qmem
        storebuffer.dcsb_cab_i = self.dcsb_cab_dc

        du = Or1200Du()
        du.rst <<= self.rst_i
        du.dcpu_cycstb_i <<= self.dcpu_cycstb_cpu
        du.dcpu_we_i <<= self.dcpu_we_cpu
        du.dcpu_adr_i <<= self.dcpu_adr_cpu
        du.dcpu_dat_lsu <<= self.dcpu_dat_cpu
        du.dcpu_dat_dc <<= self.dcpu_dat_qmem
        du.icpu_cycstb_i <<= self.icpu_cycstb_cpu
        du.ex_freeze <<= self.ex_freeze
        du.branch_op <<= self.branch_op
        du.ex_insn <<= self.ex_insn
        du.id_pc <<= self.id_pc
        du.du_dsr = self.du_dsr

        du.spr_dat_npc <<= self.spr_dat_npc
        du.rf_dataw <<= self.rf_dataw

        self.du_stall = du.du_stall
        self.du_addr = du.du_addr
        du.du_dat_i <<= self.du_dat_cpu
        self.du_dat_du = du.du_dat_o
        self.du_read = du.du_read
        self.du_write = du.du_write
        du.du_except <<= self.du_except
        self.du_hwbkpt = du.du_hwbkpt

        # du.spr_cs <<= self.spr_cs[or1200_definitions.OR1200_SPR_GROUP_DU]
        du.spr_write <<= self.spr_we
        du.spr_addr <<= self.spr_addr
        du.spr_dat_i <<= self.spr_dat_cpu
        self.spr_dat_du = du.spr_dat_o

        du.dbg_stall_i <<= self.dbg_stall_i
        du.dbg_ewt_i <<= self.dbg_ewt_i
        self.dbg_lss_o <<= du.dbg_lss_o
        self.dbg_is_o <<= du.dbg_is_o
        self.dbg_wp_o = du.dbg_wp_o
        self.dbg_bp_o = du.dbg_bp_o
        du.dbg_we_i <<= self.dbg_we_i
        du.dbg_adr_i <<= self.dbg_adr_i
        du.dbg_dat_i <<= self.dbg_dat_i
        self.dbg_dat_o = du.du_dat_o
        self.dbg_ack_o = du.dbg_ack_o

        pic = Or1200Pic()
        pic.rst <<= self.rst_i
        # pic.spr_cs = self.spr_cs[or1200_definitions.OR1200_SPR_GROUP_PIC]
        pic.spr_write <<= self.spr_we
        pic.spr_addr <<= self.spr_addr
        pic.spr_dat_i <<= self.spr_dat_cpu
        self.spr_dat_pic <<= pic.spr_dat_o
        self.pic_wakeup <<= pic.pic_wakeup
        self.sig_int <<= pic.intr

if __name__ == '__main__':
    or1200_top = Or1200_top()
    com = pyrtl.CompiledSimulation()
    f = open("com.c", 'w')
    com._create_code(lambda s: f.write(s + '\n'))
    f.close()
    essent = pyrtl.ESSENT()
    ff = open("out.c", 'w')
    essent._create_code(lambda s: ff.write(s + '\n'))
    ff.close()
    # print(pyrtl.working_block())
    # sim_trace = pyrtl.SimulationTrace()
    # sim = pyrtl.Simulation(tracer=sim_trace)
    import time
    time1 = time.perf_counter()
    com.step({
        'clk_i':0,
        'rst_i':0,
        'clmode_i':00,
        'pic_ints_i':00000000000000000000,
        'iwb_clk_i':0,
        'iwb_rst_i':0,
        'iwb_ack_i':0,
        'iwb_err_i':0,
        'iwb_rty_i':0,
        'dbg_stall_i':0,
        'dbg_ewt_i':0,
        'dbg_stb_i':0,
        'dbg_we_i':0,
        'dbg_adr_i':00000000000000000000000000000000,
        'dbg_dat_i':00000000000000000000000000000000,
        'pm_cpustall_i':1,
        'iwb_dat_i': 00000000000000000000000000000000
    })
    time2 = time.perf_counter()
    print('com', (time2 - time1) * 1000)

    time1 = time.perf_counter()
    essent.step({
        'clk_i':0,
        'rst_i':0,
        'clmode_i':00,
        'pic_ints_i':00000000000000000000,
        'iwb_clk_i':0,
        'iwb_rst_i':0,
        'iwb_ack_i':0,
        'iwb_err_i':0,
        'iwb_rty_i':0,
        'dbg_stall_i':0,
        'dbg_ewt_i':0,
        'dbg_stb_i':0,
        'dbg_we_i':0,
        'dbg_adr_i':00000000000000000000000000000000,
        'dbg_dat_i':00000000000000000000000000000000,
        'pm_cpustall_i':1,
        'iwb_dat_i': 00000000000000000000000000000000
    })
    time2 = time.perf_counter()
    print('essent', (time2 - time1) * 1000)
    # sim_trace.render_trace()
    # print(pyrtl.symbolic.gen_inputs_for_n_cycles(pyrtl.working_block()))
    # print(len(pyrtl.symbolic.gen_inputs_for_n_cycles(pyrtl.working_block())))
    # mux = {'tmp39': ['tmp39', 1]}
    # mux_clock = {'tmp39': [0, 1, 0]}
    # cycle = len(mux_clock['tmp39'])
    # stimuli = pyrtl.symbolic.solve_smt(pyrtl.working_block(), mux, mux_clock, cycle)  # , "./g")
    # print(stimuli)